<template>
  <view class="chat-container">
    <view class="chat-content">
      <uni-nav-bar left-icon="list" :title="chatTitle" @clickLeft="handleBack" :border="false" class="custom-nav-bar">
        <template #right>
          <image :src="navBarAddBtnIcon" class="nav-bar-add-btn-icon" @click="handleMore" />
        </template>
      </uni-nav-bar>

      <view class="chat-scroll-view-container">
        <scroll-view
          scroll-y
          :scroll-with-animation="false"
          :scroll-into-view="scrollToId"
          class="chat-scroll-view"
          :show-scrollbar="true"
          ref="scrollRef"
          :refresher-enabled="refresherEnabled"
          :refresher-triggered="refresherTriggered"
          @refresherrefresh="refresherrefresh">
          <view class="chat-main px-14">
            <view v-for="(item, index) in chatList" :key="item.key" class="chat-item" :id="`chatItem${item.key}`">
              <template v-if="item.role === 'USER'">
                <UserRender :content="item.content" />
              </template>
              <template v-if="item.role === 'ASSISTANT'">
                <AIRender :content="item.content" />
              </template>
            </view>
          </view>
          <view id="scroll-bottom" class="scroll-bottom"></view>
        </scroll-view>
      </view>

      <view class="chat-footer">
        <Sender @send="onSenderSubmit" @stop="onStopChat" :chatLoading="chatLoading" />
        <gao-ChatSSEClient ref="chatSSEClientRef" @onOpen="openCore" @onError="errorCore" @onMessage="messageCore" @onFinish="finishCore" />
      </view>
    </view>
  </view>
</template>

<script setup>
  import { cancelChatIngApi, getChatItemRecordsApi } from '@/api/chat';
import { createChatApi } from '@/api/chatList';
import { baseUrl } from '@/api/request';
import { useShowLoading } from '@/hooks/useShowLoading';
import navBarAddBtnIcon from '@/static/chat/nav-bar-add-btn-icon.png';
import { useChatStore } from '@/store/chat';
import { useUserStore } from '@/store/user';
import { guid } from '@/utils/utils';
import { onLoad } from '@dcloudio/uni-app';
import { nextTick, onBeforeUnmount, ref, watch } from 'vue';
import AIRender from './comp/AIRender/index';
import Sender from './comp/Sender/index';
import UserRender from './comp/UserRender/index';

  const chatStore = useChatStore();

  const userStore = useUserStore();

  const chatList = ref([]);
  // 滚动控制
  const scrollRef = ref(null);
  const scrollToId = ref('');

  const scrollTo = (scrollToTargetKey = 'scroll-bottom') => {
    scrollToId.value = scrollToTargetKey;
    nextTick(() => {
      scrollToId.value = '';
    });
  };

  // 页面数据
  const chatTitle = ref('新对话');
  const chatId = ref('');
  const agentId = ref('');

  onLoad(options => {
    console.log('获取到的参数:', options);
    agentId.value = options.agentId || '';
    if (options.chatId) {
      chatId.value = options.chatId;
      chatTitle.value = options.chatTitle || '新对话';
      setTimeout(() => {
        getChatItemRecords();
      }, 300);
    } else {
      initNewChat();
    }
  });

  const initNewChat = () => {
    chatId.value = '';
    chatTitle.value = '新对话';
    chatList.value = [];
  };

  const handleMore = () => {
    if (chatLoading.value) {
      uni.showToast({ title: '请稍等，正在生成中...', icon: 'none' });
      return;
    }
    initNewChat();
  };

  const pageInfo = ref({
    pageNum: 1,
    pageSize: 10,
    total: 0
  });
  const [handleGetChatRecordsLoading, cancelGetChatRecordsLoading] = useShowLoading(true);
  function getChatItemRecords() {
    const apiData = {
      pageNum: pageInfo.value.pageNum,
      pageSize: pageInfo.value.pageSize
    };
    handleGetChatRecordsLoading({
      title: '获取历史对话中...'
    });
    getChatItemRecordsApi(chatId.value, apiData)
      .then(res => {
        pageInfo.value.total = res.total || 0;

        const resData = res.rows || [];
        chatList.value = resData.map(item => {
          const { id, files, role } = item;
          const { content, process, think } = item.content;
          const resContent = {
            content: content,
            files: files,
            process: process,
            think: think,
            chatLoading: false
          };
          return {
            key: id,
            role,
            content: resContent
          };
        });
        setTimeout(() => {
          scrollTo();
        }, 200);
      })
      .catch(err => {})
      .finally(cancelGetChatRecordsLoading(300));
  }

  const refresherEnabled = ref(true);
  const refresherTriggered = ref(false);
  let refresherTriggeredTimes = 0;
  function refresherrefresh() {
    if (chatList.value.length >= pageInfo.value.total) {
      refresherTriggeredTimes += 1;

      uni.showToast({ title: '没有更多数据了' });
      if (refresherTriggeredTimes >= 3) {
        refresherEnabled.value = false;
      }

      refresherTriggered.value = true;
      setTimeout(() => {
        refresherTriggered.value = false;
      }, 500);
      return;
    }

    refresherTriggered.value = true;
    pageInfo.value.pageNum += 1;

    const apiData = {
      pageNum: pageInfo.value.pageNum,
      pageSize: pageInfo.value.pageSize
    };
    handleGetChatRecordsLoading({
      title: '获取历史对话中...'
    });
    getChatItemRecordsApi(chatId.value, apiData)
      .then(res => {
        pageInfo.value.total = res.total || 0;

        const scrollIntoViewKey = chatList.value.length ? `chatItem${chatList.value[0]?.key}` : '';

        const resData = res.rows || [];
        const resChatList = resData.map(item => {
          const { id, files, role } = item;
          const { content, process, think } = item.content;
          const resContent = {
            content: content,
            files: files,
            process: process,
            think: think,
            chatLoading: false
          };
          return {
            key: id,
            role,
            content: resContent
          };
        });
        chatList.value = [...resChatList, ...chatList.value];

        // nextTick(()=>{
        //   scrollTo(scrollIntoViewKey)
        // })
      })
      .catch(err => {})
      .finally(() => {
        cancelGetChatRecordsLoading(300);
        refresherTriggered.value = false;
      });
  }

  const handleBack = () => {
    chatLoading.value && onStopChat();
    uni.switchTab({
      url: '/pages/chatList/index'
    });
  };

  const chatLoading = ref(false);
  const chatSSEClientRef = ref(null);
  const chatItemId = ref(null);
  const msgTimes = ref(0);
  const msgScrollToTimes = ref(0);
  const openCore = response => {
    console.log('open sse：', response);
  };
  const errorCore = err => {
    console.log('error sse：', err);
    msgTimes.value = 0;
    chatLoading.value = false;
  };
  const messageCore = async msg => {
    const resData = msg.data;
    if (resData && resData !== '[DONE]') {
      const resDataObj = JSON.parse(resData);
      const { content: resContent, process: resProcess, think: resThinking } = resDataObj;

      if (!chatItemId.value) {
        chatItemId.value = guid();
        chatList.value.push({
          key: chatItemId.value,
          role: 'ASSISTANT',
          content: {
            content: resContent || '',
            process: resProcess || '',
            think: resThinking || '',
            chatItemLoading: true
          }
        });
        nextTick(() => {
          scrollTo();
          nextTick(() => {
            scrollTo();
          });
        });
      } else {
        if (msgTimes.value <= 0) {
          delayExecute(1500);
        }
        nextTick(async () => {
          chatList.value = chatList.value.map(item => {
            if (item.key === chatItemId.value) {
              return {
                ...item,
                content: {
                  ...item.content,
                  content: resContent ? item.content.content + resContent : item.content.content,
                  process: resProcess,
                  think: item.content.think + resThinking,
                  chatItemLoading: true
                }
              };
            }
            return item;
          });
        });

        msgTimes.value += 1;
        if (msgTimes.value >= 20) {
          msgTimes.value = 0;
          nextTick(async () => {
            msgScrollToTimes.value += 1;
            if (msgScrollToTimes.value <= 5) {
              scrollTo();
            }
          });
        }
      }
    } else {
      closeChatItemIdLoading();
    }
  };

  function delayExecute(delay) {
    const start = Date.now();
    while (Date.now() - start < delay) {}
  }

  const finishCore = () => {
    console.log('对话完成finishCore');
    chatLoading.value = false;
    nextTick(() => {
      scrollTo();
    });

    setTimeout(() => {
      scrollTo();
    }, 400);
  };
  function closeChatItemIdLoading() {
    chatList.value = chatList.value.map(item => {
      if (item.key === chatItemId.value) {
        return {
          ...item,
          content: {
            ...item.content,
            chatItemLoading: false
          }
        };
      }
      return item;
    });
  }
  watch(
    () => chatLoading.value,
    newVal => {
      if (!newVal) {
        closeChatItemIdLoading();
        msgTimes.value = 0;
        msgScrollToTimes.value = 0;
      }
    }
  );

  // 创建对话
  const [handleAddChatLoading, cancelAddChatLoading] = useShowLoading(true);
  const addChat = titleStr => {
    handleAddChatLoading({
      title: '对话创建中...'
    });
    const apiData = {
      agentId: agentId.value,
      chatTitle: ''
    };
    return createChatApi(apiData)
      .then(res => {
        chatId.value = res.data.id;
      })
      .catch(() => {})
      .finally(cancelAddChatLoading);
  };

  const onSenderSubmit = async (inputVal, fileList = []) => {
    if (!chatId.value) {
      await addChat(inputVal);
    }

    const chatContent = chatStore.isNetworking ? `帮我从网上搜一下：${inputVal}` : inputVal;
    chatList.value.push({
      key: guid(),
      role: 'USER',
      content: {
        content: chatContent,
        files: fileList
      }
    });
    chatItemId.value = null;

    start(chatContent, fileList);
  };
  const start = (inputVal, fileList) => {
    const apiData = {
      chatId: chatId.value,
      chatContent: inputVal,
      chatType: 1,
      agentId: agentId.value,
      files: fileList.map(item => item.id),
      think: chatStore.isDeepThink
    };
    chatLoading.value = true;
    chatSSEClientRef.value.startChat({
      url: `${baseUrl}/api/v1/chat/sendMsg`,
      // 请求头
      headers: {
        Authorization: userStore.token
      },
      method: 'post',
      body: apiData
    });
  };
  const stop = () => {
    chatSSEClientRef.value?.stopChat();
  };
  const onStopChat = () => {
    cancelChatIngApi({ chatId: chatId.value });
    stop();
  };

  onBeforeUnmount(() => {
    chatLoading.value && onStopChat();
  });
</script>

<style lang="scss" scoped>
  .chat-container {
    padding-top: var(--status-bar-height);
    background-image: url('@/static/chat/chat-bg.png');
    background-repeat: no-repeat;
    background-position: top;
    background-size: 100% 100%;

    .chat-content {
      height: calc(100vh - var(--status-bar-height));
      overflow: hidden;
      display: flex;
      flex-direction: column;

      :deep(.custom-nav-bar) {
        flex: none;
        height: 44px !important; // 使用动态高度
        min-height: unset !important;
        .uni-navbar__content {
          background-color: transparent !important;
          .uni-navbar__header {
            background-color: transparent !important;
          }
        }
        .nav-bar-add-btn-icon {
          width: 40rpx;
          height: 40rpx;
        }
      }

      .chat-scroll-view-container {
        flex: 1;
        display: flex;
        position: relative;
        padding-bottom: 10rpx;
        overflow: hidden;
        .chat-scroll-view {
          flex: 1;
          overflow: auto;
          .chat-main {
            padding-top: 20rpx * 2;
            .chat-item {
            }
          }
        }
      }

      .chat-footer {
        flex: none;
      }
    }
  }

  .scroll-bottom {
    width: 100%;
    height: 10rpx;
  }
</style>
